package com.softserveinc.lahire.gui;

import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Image;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.ServerSocket;

import javax.swing.JDialog;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.UIManager;

import com.softserveinc.lahire.communicator.Communicator;
import com.softserveinc.lahire.configurator.Configurator;
import com.softserveinc.lahire.server.Server;

public class TrayKeeper extends TrayIcon implements Runnable {
	private SystemTray tray;
	private TrayIcon trayIcon;
	private JPopupMenu jpmTrayMenu;
	private JMenuItem jmiStart;
	private JMenuItem jmiStop;
	private JMenuItem jmiOptionsDialog;
	private JMenuItem jmiExit;
	private EventHandler concreteEventHandler;

	public TrayKeeper() {

		super(ICON_SERVER_RUN, Communicator.getInstance().getHostPort(), null);

		try {

			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
		} finally {
			trayIcon = this;
			tray = SystemTray.getSystemTray();

			// TODO Since we have JPopupMenu in tray more addictive would be
			// place icons in addition to menu elements

			// Creating tray menu

			jpmTrayMenu = new JPopupMenu();
			jmiStart = new JMenuItem("Start");
			jmiStart.setEnabled(false);
			jmiStop = new JMenuItem("Stop");
			jmiOptionsDialog = new JMenuItem("Options");
			jmiOptionsDialog.setEnabled(false);
			jmiExit = new JMenuItem("Exit");

			// Adding JMenuItems to JPopupMenu

			jpmTrayMenu.add(jmiStart);
			jpmTrayMenu.add(jmiStop);
			jpmTrayMenu.addSeparator();
			jpmTrayMenu.add(jmiOptionsDialog);
			jpmTrayMenu.addSeparator();
			jpmTrayMenu.add(jmiExit);
			
			
			jpmTrayMenu.pack();

			concreteEventHandler = this.new EventHandler();

			// Configure MouseListeners

			jmiOptionsDialog.addMouseListener(concreteEventHandler);
			jmiExit.addMouseListener(concreteEventHandler);
			jmiStop.addMouseListener(concreteEventHandler);
			jmiStart.addMouseListener(concreteEventHandler);
			trayIcon.addMouseListener(concreteEventHandler);
		
			
		}
	}

	// Inner class for event handling

	private class EventHandler extends MouseAdapter {
		
		
		public void mousePressed(MouseEvent e){
			
			if (trayIcon.equals(e.getSource()) && e.isPopupTrigger()) { 						// POPUP for MAC
				jpmTrayMenu.setLocation(e.getX() - jpmTrayMenu.getWidth(),
						e.getY() - jpmTrayMenu.getHeight());

				jpmTrayMenu.setInvoker(jpmTrayMenu);
				
				jpmTrayMenu.setVisible(true);

			}
		}

		public void mouseReleased(MouseEvent e) {
			if (trayIcon.equals(e.getSource()) && e.isPopupTrigger()) { 						// POPUP
				jpmTrayMenu.setLocation(e.getX() - jpmTrayMenu.getWidth(),
						e.getY() - jpmTrayMenu.getHeight());

				jpmTrayMenu.setInvoker(jpmTrayMenu);
				
				jpmTrayMenu.setVisible(true);

			} else if ((jmiOptionsDialog.equals(e.getSource()) 									// OPTIONS
					&& e.getButton() == MouseEvent.BUTTON1 && !Server
						.isRunning())
					|| (trayIcon.equals(e.getSource())
							&& e.getClickCount() == 2 && !Server.isRunning())) {
				OptionsDialog.getInstance().setAlwaysOnTop(true);
				// OptionsDialog.getInstance();
			} else if (jmiExit.equals(e.getSource()) 											// EXIT
					&& e.getButton() == MouseEvent.BUTTON1) {
				Server.exitServer();
			} else if (jmiStop.equals(e.getSource()) 											// STOP
					&& e.getButton() == MouseEvent.BUTTON1
					&& Server.isRunning()) {
				Server.stopServer();
				trayIcon.setImage(ICON_SERVER_STOP);
				trayIcon.displayMessage("Server stoped", "Server stoped",
						TrayIcon.MessageType.INFO);
				trayIcon.setToolTip("Server stopped");
				jmiStart.setEnabled(true);
				jmiOptionsDialog.setEnabled(true);
				jmiStop.setEnabled(false);
			} else if (jmiStart.equals(e.getSource()) 											// START
					&& e.getButton() == MouseEvent.BUTTON1
					&& !Server.isRunning()) {

				// Dispose OptionsDialog when starting the server

				if (OptionsDialog.getInstance() == null
						|| OptionsDialog.getInstance().isVisible()) {
					OptionsDialog.getInstance().dispose();
				}
				if (Server.startServer()) {
					trayIcon.setImage(ICON_SERVER_RUN);
					trayIcon.displayMessage("Server started",
							"Server started on "
									+ Communicator.getInstance().getHostPort(),
							TrayIcon.MessageType.INFO);
					trayIcon.setToolTip(Communicator.getInstance().getHostPort());
					jmiStart.setEnabled(false);
					jmiOptionsDialog.setEnabled(false);
					jmiStop.setEnabled(true);
				} else {
					trayIcon.setToolTip("Server stopped");
					trayIcon.displayMessage("Server cannot start",
							"Port already used by another process",
							MessageType.ERROR);
				}

			}
		}
	}

	public void run() {
		try {
			tray.add(trayIcon);
			trayIcon.displayMessage("Server started", "Server started on "
					+ Communicator.getInstance().getHostPort(),
					TrayIcon.MessageType.INFO);
		} catch (AWTException e) {
			e.printStackTrace();
		}
	}

	public void stopMe() {

		// Remove icon from the tray

		tray.remove(trayIcon);

		// Kill OptionsDialog

		OptionsDialog.getInstance().dispose();
	}

	static final Image ICON_SERVER_STOP = Toolkit.getDefaultToolkit().getImage(
			"res/img/serverStop.gif");
	static final Image ICON_SERVER_RUN = Toolkit.getDefaultToolkit().getImage(
			"res/img/serverRun.gif");

}